package com.mini.service;

import com.mini.conditon.BussinessPageInfoCondition;
import com.mini.constant.RedisKeyConst;
import com.mini.model.BussinessPageInfo;
import com.mini.repository.BussinessPageInfoRepository;
import com.mini.util.CalendarUtil;
import com.mini.vo.PageResultVO;
import com.mini.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * xyf
 */
@Service
@Slf4j
public class BussinessPageInfoService extends BaseService {

    @Autowired
    private BussinessPageInfoRepository repository;

    @Autowired
    private MiniAdminService miniAdminService;

    public BussinessPageInfo findById(Long id) {
        String businessInfoKey = RedisKeyConst.getBusinessPageSite(id);
        Object o = redisTemplate.opsForValue().get(businessInfoKey);
        if (o == null) {
            BussinessPageInfo one = repository.findOne(id);
            if (one != null) {
                redisTemplate.opsForValue().set(businessInfoKey, one, 30, TimeUnit.DAYS);
            }
            return one;
        }
        return repository.findOne(id);
    }

    public BussinessPageInfo save(BussinessPageInfo bussinessPageInfo) {
        bussinessPageInfo = repository.saveAndFlush(bussinessPageInfo);
        redisTemplate.delete(RedisKeyConst.getBusinessPageSite(bussinessPageInfo.getId()));
        return bussinessPageInfo;
    }

    public List<BussinessPageInfo> findPageNameOk(String pageName) {
        List<BussinessPageInfo> relist = repository.findByPageName(pageName);
        return relist;
    }


    public PageResultVO<BussinessPageInfo> page(BussinessPageInfoCondition condition, String token) {
        PageResultVO<BussinessPageInfo> resultVO = new PageResultVO<>();
        Pageable pageable = buildPageRequest(condition.getPageNumber(), condition.getPageSize(), new Sort(Sort.Direction.DESC, "updateTime"));
        Page<BussinessPageInfo> page = repository.findAll(new Specification<BussinessPageInfo>() {
            @Override
            public Predicate toPredicate(Root<BussinessPageInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (StringUtils.isNotBlank(condition.getTplName())) {
                    predicates.add(criteriaBuilder.equal(root.get("tplName").as(String.class), condition.getTplName()));
                }
                if (condition.getFzId() != null && 0 != condition.getFzId().longValue()) {
                    predicates.add(criteriaBuilder.equal(root.get("fzId").as(Long.class), condition.getFzId()));
                } else {
                    if (condition.getUserId() != null && 0 != condition.getUserId().intValue()) {
                        List<Long> userids = scopedAdvertisingUserIds(condition.getUserId());
                        CriteriaBuilder.In<Long> in = criteriaBuilder.in(root.get("fzId"));
                        Iterator<Long> it = userids.iterator();
                        while (it.hasNext()) {
                            in.value(it.next());
                        }
                        predicates.add(in);
                    }
                }


                if (condition.getStates() != null && -1 != condition.getStates().intValue()) {

                    predicates.add(criteriaBuilder.equal(root.get("states").as(Integer.class), condition.getStates()));
                }

                if (StringUtils.isNotBlank(condition.getSearch())) {
                    String search = condition.getSearch();
                    search = search.replaceAll("YM", "");
                    long id = 0;
                    try {
                        id = Long.parseLong(search);
                    } catch (Exception e) {

                    }
                    Predicate p1 = criteriaBuilder.equal(root.get("id").as(Long.class), id);
                    Predicate p2 = criteriaBuilder.like(root.get("pageName").as(String.class), "%" + condition.getSearch() + "%");
                    predicates.add(criteriaBuilder.or(p1, p2));
                }

                if (condition.getDomainId() != null && 0 != condition.getDomainId().intValue()) {
                    predicates.add(criteriaBuilder.equal(root.get("domainId").as(Long.class), condition.getDomainId()));
                }

                if (StringUtils.isNotBlank(condition.getChannelCode())) {
                    predicates.add(criteriaBuilder.equal(root.get("channelCode").as(String.class), condition.getChannelCode()));
                }

                if (condition.getOcpmType() != null && 0 != condition.getOcpmType().intValue()) {
                    predicates.add(criteriaBuilder.equal(root.get("ocpmType").as(Integer.class), condition.getOcpmType()));
                }

                //查小程序类型的页面
                if (condition.getPageType() != null && 2 == condition.getPageType().intValue()) {
                    predicates.add(criteriaBuilder.equal(root.get("pageType").as(Integer.class), condition.getPageType()));
                }

                //查非小程序类型的页面
                if (condition.getPageType() != null && -1 == condition.getPageType().intValue()) {
                    predicates.add(criteriaBuilder.notEqual(root.get("pageType").as(Integer.class), 2));
                }

                //查非小程序类型的页面
                if (StringUtils.isNotBlank(condition.getXcxAppId())) {
                    predicates.add(criteriaBuilder.equal(root.get("xcxAppid").as(String.class), condition.getXcxAppId()));
                }


                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        }, pageable);
        setFzName(token, page);//设置负责人信息
        resultVO.setTotal(page.getTotalElements());
        resultVO.setRows(page.getContent());
        return resultVO;
    }

    public void setFzName(String token, Page<BussinessPageInfo> page) {
        List<BussinessPageInfo> relist = page.getContent();
        Set<Long> userset = new HashSet<>();
        if (relist != null) {
            for (BussinessPageInfo bussinessPageInfo : relist) {
                userset.add(bussinessPageInfo.getFzId());
            }
            Map<String, UserVO> m = getUserMap(userset);
            if (!m.isEmpty()) {
                for (BussinessPageInfo bussinessPageInfo : relist) {
                    if (m.containsKey(bussinessPageInfo.getFzId() + "")) {
                        bussinessPageInfo.setFzName(m.get(bussinessPageInfo.getFzId() + "").getNickname());
                    }
                }
            }

        }

    }

    public Map<String, UserVO> getUserMap(Set<Long> userIds) {
        Map<String, UserVO> remp = new HashMap<>();
        List<UserVO> re = miniAdminService.batchFindUserList(userIds);
        for (UserVO userVO : re) {
            remp.put(userVO.getId() + "", userVO);
        }
        return remp;
    }

    public void delete(BussinessPageInfo bussinessPageInfo) {
        repository.delete(bussinessPageInfo);
    }

    /**
     * @return
     */
   /* private Specification<BussinessPageInfo> getPageSpecification(String tplName,Long domainId,Integer states){

        return new Specification<BussinessPageInfo>() {
            @Override
            public Predicate toPredicate(Root<BussinessPageInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(lessonSiteId != null && 0!= lessonSiteId.intValue()){
                    predicates.add(criteriaBuilder.equal(root.get("lessonSiteId").as(Long.class), lessonSiteId));
                }
                if(userId != null && 0!= userId.intValue()){
                    predicates.add(criteriaBuilder.equal(root.get("createUser").as(Long.class),userId));
                }
                if(states != null){
                    predicates.add(criteriaBuilder.equal(root.get("states").as(Integer.class),states));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }
*/


    /**
     * 查询当前用户的
     * @param condition
     * @return
     */
    public List<BussinessPageInfo> todayNewPage(BussinessPageInfoCondition condition){
        List<BussinessPageInfo> page = repository.findAll(new Specification<BussinessPageInfo>() {
            @Override
            public Predicate toPredicate(Root<BussinessPageInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if(condition.getUserId() != null && 0 != condition.getUserId().intValue()){
                    List<Long> userids = scopedAdvertisingUserIds(condition.getUserId());
                    CriteriaBuilder.In<Long> in = criteriaBuilder.in(root.get("fzId"));
                    Iterator<Long> it = userids.iterator();
                    while (it.hasNext()){
                        in.value(it.next());
                    }
                    predicates.add(in);
                }
                String beginTime = CalendarUtil.getShortDateString(new Date());
                predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("updateTime").as(String.class) , beginTime + " 00:00:00"));

                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        });

        return page;
    }

}
